package org.example.mrrope.dto;


import lombok.Data;
import org.example.mrrope.enums.ResultEnums;

/**
 * @ClassName R
 * @Description 返回参数
 * @Author MZ
 * @Date 2023/11/10 16:22
 */
@Data
public class R<T> {

    private Integer code;
    private String message;
    private T data;

    /**
     * 构造函数私有化
     */
    private R() {
    }

    /**
     * 返回数据
     *
     * @param data
     * @param <T>
     * @return
     */
    protected static <T> R<T> build(T data) {
        R<T> res = new R<T>();
        if (data != null) {
            res.setData(data);
        }
        return res;
    }

    protected static <T> R<T> build(T body, ResultEnums enums) {
        R<T> res = build(body);
        res.setCode(enums.getCode());
        res.setMessage(enums.getMessage());
        return res;
    }

    private static <T> R<T> build(T body, ResultEnums otherReason, String msg) {
        R<T> res = build(body);
        res.setCode(otherReason.getCode());
        res.setMessage(msg);
        return res;
    }

    /**
     * 返回成功结果（无data）
     *
     * @param <T>
     * @return
     */
    public static <T> R<T> ok() {
        return R.ok(null);
    }

    /**
     * 返回成功结果 ，附加data
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> R<T> ok(T data) {
        R<T> result = build(data);
        return build(data, ResultEnums.SUCCESS);
    }


    /**
     * 返回默认的失败结果 系统异常
     *
     * @return
     */
    public static <T> R<T> error() {
        return R.error(ResultEnums.SYS_ERROR);
    }

    /**
     * 操作失败（返回枚举类的结果）
     *
     * @param enums
     * @param <T>
     * @return
     */
    public static <T> R<T> error(ResultEnums enums) {
        R<T> result = build(null, enums);
        return build(null, enums);
    }

    /**
     * 自定义错误信息
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> R<T> error(String msg) {
        ResultEnums otherReason = ResultEnums.OTHER_REASON;
        R<T> result = build(null, otherReason, msg);
        return build(null, otherReason, msg);
    }

    public R<T> message(String msg) {
        this.setMessage(msg);
        return this;
    }

    public R<T> code(Integer code) {
        this.setCode(code);
        return this;
    }

}
